package com.dongnam.quanly.web.danhmuc.nhomdoitac;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;

import jxl.Cell;
import jxl.CellType;
import jxl.Sheet;
import jxl.Workbook;
import jxl.format.Alignment;
import jxl.read.biff.BiffException;
import jxl.write.Label;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;

import org.primefaces.context.RequestContext;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.StreamedContent;
import org.primefaces.model.TreeNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.dongnam.quanly.common.controller.NhomDoiTacController;
import com.dongnam.quanly.common.exceptions.DatabaseException;
import com.dongnam.quanly.common.model.NhomDoiTac;
import com.dongnam.quanly.common.model.TaiKhoanNganHang;
import com.dongnam.quanly.web.UserBean;
import com.dongnam.quanly.web.util.WebUtil;

@ManagedBean(name = "NhomDoiTacBean")
@SessionScoped
public class NhomDoiTacBean implements Serializable {
	private static final Logger logger = LoggerFactory.getLogger(NhomDoiTacBean.class);
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	@ManagedProperty(value = "#{UserBean}")
	private UserBean userBean;
	private TreeNode nhomDoiTacRoot;
	private TreeNode selectedNode;

	// for add NhomDoiTac
	private String maNhomDoiTac;
	private String tenNhomDoiTac;
	private String thuocNhomDoiTac;
	private String diengiai;
	private boolean edit = false;
	// for download file
	private StreamedContent file;

	// for load danh sach nhom doi tac
	private NhomDoiTacController nhomDoiTacController;
	private List<NhomDoiTac> listnhomDoiTac;
	private boolean flag = false;

	// for edit nhomDoiTac
	private NhomDoiTac selectedNhomDoiTac;

	public NhomDoiTacController getNhomDoiTacController() {

		if (nhomDoiTacController == null)
			nhomDoiTacController = new NhomDoiTacController();
		return nhomDoiTacController;
	}

	public void downloadFileCSV() {
		File excelfile = new File("NHOM_DOI_TAC.xls");
		List<NhomDoiTac> list = getNhomDoiTacController().findAll();
		int length = list.size();
		try {
			WritableWorkbook workbook = Workbook.createWorkbook(excelfile);
			WritableSheet sheet = workbook.createSheet("First Sheet", 0);

			// style for title
			WritableFont titlefont = new WritableFont(WritableFont.ARIAL, 16, WritableFont.BOLD);
			WritableCellFormat titleformat = new WritableCellFormat(titlefont);
			titleformat.setAlignment(Alignment.LEFT);
			titleformat.setWrap(false);

			// style for content
			WritableFont contentfont = new WritableFont(WritableFont.ARIAL, 13);
			WritableCellFormat contentformat = new WritableCellFormat(contentfont);
			contentformat.setAlignment(Alignment.LEFT);
			contentformat.setWrap(false);

			// thiet lap tieu de
			sheet.setColumnView(0, 30);
			sheet.setColumnView(1, 30);
			sheet.setColumnView(2, 30);
			sheet.setColumnView(3, 30);

			sheet.addCell(new Label(0, 0, "Mã Nhóm", titleformat));
			sheet.addCell(new Label(1, 0, "Tên Nhóm", titleformat));
			sheet.addCell(new Label(2, 0, "Thuộc Nhóm", titleformat));
			sheet.addCell(new Label(3, 0, "Diễn Giải", titleformat));

			for (int i = 0; i < length; i++) {

				sheet.addCell(new Label(0, i + 1, list.get(i).getMaNhomDoiTac(), contentformat));
				sheet.addCell(new Label(1, i + 1, list.get(i).getTenNhomDoiTac(), contentformat));
				sheet.addCell(new Label(2, i + 1, list.get(i).getThuocNhomDoiTac(), contentformat));
				sheet.addCell(new Label(3, i + 1, list.get(i).getDienGiai(), contentformat));

			}

			workbook.write();
			workbook.close();

			file = new DefaultStreamedContent(new FileInputStream(excelfile), "application/csv", "NHOM_DOI_TAC.xls",
					"UTF-8");

		} catch (IOException | WriteException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

	}

	public void handleFileUpload(FileUploadEvent event) {

		logger.debug("process upload file ");
		Workbook w;
		boolean rollback = false;
		List<NhomDoiTac> list = new ArrayList<NhomDoiTac>();
		try {
			w = Workbook.getWorkbook(event.getFile().getInputstream());
			// Get the first sheet
			Sheet sheet = w.getSheet(0);
			// Loop over first 10 column and lines

			for (int row = 1; row < sheet.getRows(); row++) {

				Cell cell_ma_ndt = sheet.getCell(0, row);
				Cell cell_ten_ndt = sheet.getCell(1, row);
				Cell cell_thuoc_ndt = sheet.getCell(2, row);
				Cell cell_dienGiai = sheet.getCell(3, row);

				NhomDoiTac nhomdoitac = new NhomDoiTac();
				nhomdoitac.setMaNhomDoiTac(cell_ma_ndt.getContents());
				nhomdoitac.setTenNhomDoiTac(cell_ten_ndt.getContents());
				nhomdoitac.setThuocNhomDoiTac(cell_thuoc_ndt.getContents());
				nhomdoitac.setDienGiai(cell_dienGiai.getContents());
				boolean isHasChild = false;
				for (int i = 0; i < sheet.getRows(); i++) {
					Cell cell_thuoc_ndt_test = sheet.getCell(2, i);
					if (cell_ma_ndt.getContents().equals(cell_thuoc_ndt_test.getContents())) {
						isHasChild = true;
						break;
					}
				}
				nhomdoitac.setIsHasChild(isHasChild);
				list.add(nhomdoitac);
			}
		} catch (BiffException | IOException e) {
			e.printStackTrace();
			rollback = true;
			FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Unsuccessful : Database error : "
					+ e.getMessage(), "");
			FacesContext.getCurrentInstance().addMessage(null, msg);
		}

		if (!rollback) {
			getNhomDoiTacController().batchSaveOrUpdate(list);
		}

		loadNhomDoiTac();

	}

	public void resetFormAdd() {
		maNhomDoiTac = null;
		tenNhomDoiTac = null;
		thuocNhomDoiTac = null;
		diengiai = null;
	}

	public void notifyAdd() {
		edit = false;
		resetFormAdd();

		listnhomDoiTac = getNhomDoiTacController().findAll();
	}

	public void findNote(TreeNode root, NhomDoiTac nhomDoiTac) {

		if (!flag) {
			if (root.isLeaf()) {

				if (((NhomDoiTac) root.getData()).getMaNhomDoiTac().equals(nhomDoiTac.getMaNhomDoiTac())) {
					flag = true;
					this.selectedNode = root;
				}
			}

			else {

				if (root.getData() != null) {
					if (((NhomDoiTac) root.getData()).getMaNhomDoiTac().equals(nhomDoiTac.getMaNhomDoiTac())) {
						flag = true;
						this.selectedNode = root;
					} else {
						List<TreeNode> listnode = root.getChildren();
						int length = listnode.size();
						for (int i = 0; i < length; i++) {
							findNote(listnode.get(i), nhomDoiTac);
						}
					}
				} else {
					List<TreeNode> listnode = root.getChildren();
					int length = listnode.size();
					for (int i = 0; i < length; i++) {
						findNote(listnode.get(i), nhomDoiTac);
					}
				}

			}
		}
	}

	public void notifyEdit(NhomDoiTac nhomDoiTac) {
		edit = true;
		this.selectedNhomDoiTac = nhomDoiTac;
		maNhomDoiTac = this.selectedNhomDoiTac.getMaNhomDoiTac();
		tenNhomDoiTac = this.selectedNhomDoiTac.getTenNhomDoiTac();
		thuocNhomDoiTac = this.selectedNhomDoiTac.getThuocNhomDoiTac();
		diengiai = this.selectedNhomDoiTac.getDienGiai();

		List<String> listtest = new ArrayList<String>();

		this.flag = false;
		this.selectedNode = null;
		findNote(this.nhomDoiTacRoot, nhomDoiTac);
		if (this.selectedNode != null)

			deepTree(this.selectedNode, listtest);

		for (int i = 0; i < listtest.size(); i++) {
			logger.info(listtest.get(i) + "hsadb");
		}

		if (listtest.size() != 0)
			listnhomDoiTac = getNhomDoiTacController().listNhomDoiTacExclude(listtest);
		else
			listnhomDoiTac = getNhomDoiTacController().findAll();
	}

	public void deepTree(TreeNode root, List<String> list) {
		if (root.isLeaf()) {
			logger.info("Name " + ((NhomDoiTac) root.getData()).getMaNhomDoiTac());
			list.add(((NhomDoiTac) root.getData()).getMaNhomDoiTac());
		} else {
			logger.info("Name " + ((NhomDoiTac) root.getData()).getMaNhomDoiTac());
			list.add(((NhomDoiTac) root.getData()).getMaNhomDoiTac());
			List<TreeNode> listnode = root.getChildren();
			int length = listnode.size();
			for (int i = 0; i < length; i++) {
				deepTree(listnode.get(i), list);
			}
		}
	}

	public void removeNhomDoiTac() {

		if (this.selectedNhomDoiTac != null) {
			getNhomDoiTacController().makeTransient(this.selectedNhomDoiTac);

			List<String> listtest = new ArrayList<String>();

			this.flag = false;
			this.selectedNode = null;
			findNote(this.nhomDoiTacRoot, this.selectedNhomDoiTac);
			if (this.selectedNode != null)

				deepTree(this.selectedNode, listtest);

			for (int i = 0; i < listtest.size(); i++) {
				logger.info(listtest.get(i) + "hsadb");
			}

			getNhomDoiTacController().batchDelete(getNhomDoiTacController().listNhomDoiTacInclude(listtest));
			loadNhomDoiTac();
			listnhomDoiTac = getNhomDoiTacController().findAll();
		}

	}

	private void setParent() {
		if (!this.thuocNhomDoiTac.equals("root")) {
			NhomDoiTac pbparent = getNhomDoiTacController().findById(this.thuocNhomDoiTac, false);

			if (pbparent != null) {
				logger.debug("Nhom Doi Tac parent: " + pbparent.getMaNhomDoiTac());
				pbparent.setIsHasChild(Boolean.TRUE);
				getNhomDoiTacController().makePersistent(pbparent);
			}
		}
	}

	public void save() {

		RequestContext context = RequestContext.getCurrentInstance();
		try {
			if (edit) {

				if (this.selectedNhomDoiTac != null) {

					logger.debug("Edit new NhomDoiTac");

					this.selectedNhomDoiTac.setUpdateBy(userBean.getUser().getUserId());
					this.selectedNhomDoiTac.setMaNhomDoiTac(this.maNhomDoiTac);
					this.selectedNhomDoiTac.setTenNhomDoiTac(this.tenNhomDoiTac);
					this.selectedNhomDoiTac.setThuocNhomDoiTac(this.thuocNhomDoiTac);
					this.selectedNhomDoiTac.setDienGiai(this.diengiai);

					getNhomDoiTacController().makePersistent(this.selectedNhomDoiTac);
					// change state of parent
					setParent();

					context.addCallbackParam("opSuccess", true);
				}

			} else {

				logger.debug("Add new NhomDoiTac");
				NhomDoiTac pb = new NhomDoiTac();
				pb.setCreateBy(userBean.getUser().getUserId());
				pb.setUpdateBy(userBean.getUser().getUserId());

				pb.setMaNhomDoiTac(this.maNhomDoiTac);
				pb.setTenNhomDoiTac(this.tenNhomDoiTac);
				pb.setThuocNhomDoiTac(this.thuocNhomDoiTac);
				pb.setDienGiai(this.diengiai);
				pb.setIsHasChild(Boolean.FALSE);

				getNhomDoiTacController().makePersistent(pb);

				// change state of parent
				if (!this.thuocNhomDoiTac.equals("root")) {
					setParent();
				}

				listnhomDoiTac = getNhomDoiTacController().findAll();
				context.addCallbackParam("opSuccess", true);

			}
		} catch (DatabaseException e) {
			e.printStackTrace();
			logger.debug("Database error" + e.getMessage());
			context.addCallbackParam("opSuccess", false);

			FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Unsuccessful : Database error : "
					+ e.getMessage(), "");
			FacesContext.getCurrentInstance().addMessage(null, msg);
		}

		loadNhomDoiTac();

	}

	public void loadNhomDoiTac() {
		if (nhomDoiTacRoot == null)
			nhomDoiTacRoot = new DefaultTreeNode();

		nhomDoiTacRoot.getChildren().clear();

		List<NhomDoiTac> listgroup = loadParents();
		List<NhomDoiTac> listchild = loadChilds();
		createListNhomDoiTac("root", nhomDoiTacRoot, listgroup, listchild, listgroup.size(), listchild.size());

		this.nhomDoiTacRoot.setExpanded(true);

	}

	public boolean isEdit() {
		return edit;
	}

	public void setEdit(boolean edit) {
		this.edit = edit;
	}

	private List<NhomDoiTac> loadChilds() {
		NhomDoiTac exam = new NhomDoiTac();
		exam.setIsHasChild(Boolean.FALSE);
		return getNhomDoiTacController().findByExample(exam);
	}

	private List<NhomDoiTac> loadParents() {
		NhomDoiTac exam = new NhomDoiTac();
		exam.setIsHasChild(Boolean.TRUE);
		return getNhomDoiTacController().findByExample(exam);

	}

	public void createListNhomDoiTac(String parentID, TreeNode parent, List<NhomDoiTac> listgroups,
			List<NhomDoiTac> listnhomDoiTac, int lengthgroups, int lenghtnhomDoiTac) {

		for (int i = 0; i < lengthgroups; i++) {
			if (listgroups.get(i).getThuocNhomDoiTac().equals(parentID)) {
				TreeNode group = new DefaultTreeNode(listgroups.get(i), parent);
				createListNhomDoiTac(listgroups.get(i).getMaNhomDoiTac(), group, listgroups, listnhomDoiTac,
						lengthgroups, lenghtnhomDoiTac);
			}
		}

		for (int j = 0; j < lenghtnhomDoiTac; j++) {

			if (listnhomDoiTac.get(j).getThuocNhomDoiTac().equals(parentID)) {
				new DefaultTreeNode(listnhomDoiTac.get(j), parent);
			}
		}
	}

	public StreamedContent getFile() {
		return file;
	}

	public void setFile(StreamedContent file) {
		this.file = file;
	}

	public UserBean getUserBean() {
		return userBean;
	}

	public void setUserBean(UserBean userBean) {
		this.userBean = userBean;
	}

	public TreeNode getNhomDoiTacRoot() {
		return nhomDoiTacRoot;
	}

	public void setNhomDoiTacRoot(TreeNode nhomDoiTacRoot) {
		this.nhomDoiTacRoot = nhomDoiTacRoot;
	}

	public String getMaNhomDoiTac() {
		return maNhomDoiTac;
	}

	public void setMaNhomDoiTac(String maNhomDoiTac) {
		this.maNhomDoiTac = maNhomDoiTac;
	}

	public String getTenNhomDoiTac() {
		return tenNhomDoiTac;
	}

	public void setTenNhomDoiTac(String tenNhomDoiTac) {
		this.tenNhomDoiTac = tenNhomDoiTac;
	}

	public String getThuocNhomDoiTac() {
		return thuocNhomDoiTac;
	}

	public void setThuocNhomDoiTac(String thuocNhomDoiTac) {
		this.thuocNhomDoiTac = thuocNhomDoiTac;
	}

	public String getDiengiai() {
		return diengiai;
	}

	public void setDiengiai(String diengiai) {
		this.diengiai = diengiai;
	}

	public List<NhomDoiTac> getListnhomDoiTac() {
		return listnhomDoiTac;
	}

	public void setNhomDoiTacController(NhomDoiTacController nhomDoiTacController) {
		this.nhomDoiTacController = nhomDoiTacController;
	}

	public void setListnhomDoiTac(List<NhomDoiTac> listnhomDoiTac) {
		this.listnhomDoiTac = listnhomDoiTac;
	}

	public NhomDoiTac getSelectedNhomDoiTac() {
		return selectedNhomDoiTac;
	}

	public void setSelectedNhomDoiTac(NhomDoiTac selectedNhomDoiTac) {
		this.selectedNhomDoiTac = selectedNhomDoiTac;
	}

	public void reloadPage() {
		listnhomDoiTac = getNhomDoiTacController().findAll();
		loadNhomDoiTac();
		WebUtil.redirect("/pages/danhmuc/nhomDoiTac.xhtml");
	}

	public TreeNode getSelectedNode() {
		return selectedNode;
	}

	public void setSelectedNode(TreeNode selectedNode) {
		this.selectedNode = selectedNode;
	}

}
